home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / C / SHA.ZIP / sha.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-02  |  9.7 KB  |  368 lines

  1. /********************************************************************
  2. ** Calculate the secure hash algorithm for a set of files.
  3. ** Algorithm from
  4. **    Stallings W, "SHA: the secure hash algorithm."
  5. **    Dr. Dobb's Journal, #213 (April 1994).
  6. **
  7. ** usage: sha [file ...]
  8. **
  9. ** Copyright 1994, G. Ralph Kuntz
  10. **
  11. ** This program is free software; you can redistribute it and/or modify
  12. ** it under the terms of the GNU General Public License as published by
  13. ** the Free Software Foundation; either version 2 of the License, or
  14. ** (at your option) any later version.
  15. **
  16. ** This program is distributed in the hope that it will be useful,
  17. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. ** GNU General Public License for more details.
  20. **
  21. ** You should have received a copy of the GNU General Public License
  22. ** along with this program; if not, write to the Free Software
  23. ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24. ********************************************************************/
  25.  
  26. #include        <stdlib.h>
  27. #include        <stdio.h>
  28.  
  29. #define BLOCK_COUNT  (512L / 8)               /* 512 bits into bytes */
  30.  
  31. typedef enum { FALSE, TRUE } Bool;
  32.  
  33. unsigned char *buffer;
  34. Bool wholeFile;
  35. long place;
  36. long size;
  37. char smallBuffer[BLOCK_COUNT];
  38.  
  39. void
  40. initBuffer(FILE *fp)
  41. {
  42.   wholeFile = FALSE;
  43.   place = 0L;
  44.   size = 0L;
  45.   if (fseek(fp, 0L, SEEK_END) == 0) {         /* Can get to EOF */
  46.     size = ftell(fp);
  47.     if (size != -1) {                         /* Can get position of EOF */
  48.       long trueSize = size;
  49.       size = (size & ~(BLOCK_COUNT - 1)) + BLOCK_COUNT;   /* Round up to next
  50.                                                           ** multiple of
  51.                                                           ** BLOCK_COUNT */
  52.       if ((buffer = (char *) malloc((size_t) size)) != NULL) {  /* Can
  53.                                                                 ** allocate
  54.                                                                 ** enough
  55.                                                                 ** memory */
  56.         rewind(fp);
  57.         if (fread(buffer, 1, trueSize, fp) == (size_t) trueSize) {
  58.           long i;
  59.           wholeFile = TRUE;
  60.           buffer[trueSize] = 0x80;            /* First pad byte */
  61.           for (i = trueSize + 1; i < size - 4; i++)
  62.             buffer[i] = 0;
  63.           buffer[i++] = (unsigned char) ((trueSize & 0xff000000L) >> 24);
  64.           buffer[i++] = (unsigned char) ((trueSize & 0xff0000L) >> 16);
  65.           buffer[i++] = (unsigned char) ((trueSize & 0xff00) >> 8);
  66.           buffer[i] = (unsigned char) (trueSize & 0xff);
  67.           return;
  68.         } else {
  69.           rewind(fp);
  70.           free(buffer);
  71.         }
  72.       }
  73.     }
  74.   }                                           /* Cannot get to EOF */
  75.   rewind(fp);
  76.   buffer = smallBuffer;
  77. }
  78.  
  79. void
  80. closeBuffer(void)
  81. {
  82.   if (wholeFile)
  83.     free(buffer);
  84. }
  85.  
  86. Bool
  87. readBuffer(FILE *fp, unsigned long *destBuffer)
  88. {
  89.   unsigned long ulTemp;
  90.   unsigned char *pPlace;
  91.   int i;
  92.   if (!wholeFile) {                           /* Reading from small buffer */
  93.     static long totalBytes = 0;
  94.     int count;
  95.     pPlace = buffer;
  96.     if ((count = (int) fread(buffer, 1, BLOCK_COUNT, fp)) < BLOCK_COUNT) {
  97.       if (count == 0 && feof(fp) != 0)
  98.         return FALSE;
  99.       totalBytes += count;
  100.       buffer[count] = 0x80;                   /* Pad the buffer */
  101.       for (i = count + 1; i < BLOCK_COUNT - 4; i++)
  102.         buffer[i] = 0; 
  103.       buffer[i++] = (totalBytes & 0xff000000) >> 24;
  104.       buffer[i++] = (totalBytes & 0xff0000) >> 16;
  105.       buffer[i++] = (totalBytes & 0xff00) >> 8;
  106.       buffer[i] = totalBytes & 0xff;
  107.     } else                                    /* Full buffer */
  108.       totalBytes += BLOCK_COUNT;
  109.     place = 0;
  110.   } else {                                    /* Reading from big buffer */
  111.       if (place >= size)
  112.         return FALSE;
  113.       pPlace = &buffer[place];
  114.   }
  115.   for (i = 0; i < (BLOCK_COUNT / 4); i++) {
  116.     ulTemp = ((unsigned long) *pPlace << 24) |
  117.       ((unsigned long) *(pPlace + 1) << 16) |
  118.       ((unsigned long) *(pPlace + 2) << 8) |
  119.       (unsigned long) *(pPlace + 3);
  120.     destBuffer[i] = ulTemp;
  121.     pPlace += 4;
  122.   }
  123.   place += BLOCK_COUNT;
  124.   return TRUE;
  125. }
  126.  
  127. unsigned long mdQ[5];
  128.  
  129. const unsigned long kReg[] = {
  130.   0x5a827999L,
  131.   0x5a827999L,
  132.   0x5a827999L,
  133.   0x5a827999L,
  134.   0x5a827999L,
  135.   0x5a827999L,
  136.   0x5a827999L,
  137.   0x5a827999L,
  138.   0x5a827999L,
  139.   0x5a827999L,
  140.   0x5a827999L,
  141.   0x5a827999L,
  142.   0x5a827999L,
  143.   0x5a827999L,
  144.   0x5a827999L,
  145.   0x5a827999L,
  146.   0x5a827999L,
  147.   0x5a827999L,
  148.   0x5a827999L,
  149.   0x5a827999L,
  150.   0x6ed9eba1L,
  151.   0x6ed9eba1L,
  152.   0x6ed9eba1L,
  153.   0x6ed9eba1L,
  154.   0x6ed9eba1L,
  155.   0x6ed9eba1L,
  156.   0x6ed9eba1L,
  157.   0x6ed9eba1L,
  158.   0x6ed9eba1L,
  159.   0x6ed9eba1L,
  160.   0x6ed9eba1L,
  161.   0x6ed9eba1L,
  162.   0x6ed9eba1L,
  163.   0x6ed9eba1L,
  164.   0x6ed9eba1L,
  165.   0x6ed9eba1L,
  166.   0x6ed9eba1L,
  167.   0x6ed9eba1L,
  168.   0x6ed9eba1L,
  169.   0x6ed9eba1L,
  170.   0x8f1bbcdcL,
  171.   0x8f1bbcdcL,
  172.   0x8f1bbcdcL,
  173.   0x8f1bbcdcL,
  174.   0x8f1bbcdcL,
  175.   0x8f1bbcdcL,
  176.   0x8f1bbcdcL,
  177.   0x8f1bbcdcL,
  178.   0x8f1bbcdcL,
  179.   0x8f1bbcdcL,
  180.   0x8f1bbcdcL,
  181.   0x8f1bbcdcL,
  182.   0x8f1bbcdcL,
  183.   0x8f1bbcdcL,
  184.   0x8f1bbcdcL,
  185.   0x8f1bbcdcL,
  186.   0x8f1bbcdcL,
  187.   0x8f1bbcdcL,
  188.   0x8f1bbcdcL,
  189.   0x8f1bbcdcL,
  190.   0xca62c1d6L,
  191.   0xca62c1d6L,
  192.   0xca62c1d6L,
  193.   0xca62c1d6L,
  194.   0xca62c1d6L,
  195.   0xca62c1d6L,
  196.   0xca62c1d6L,
  197.   0xca62c1d6L,
  198.   0xca62c1d6L,
  199.   0xca62c1d6L,
  200.   0xca62c1d6L,
  201.   0xca62c1d6L,
  202.   0xca62c1d6L,
  203.   0xca62c1d6L,
  204.   0xca62c1d6L,
  205.   0xca62c1d6L,
  206.   0xca62c1d6L,
  207.   0xca62c1d6L,
  208.   0xca62c1d6L,
  209.   0xca62c1d6L,
  210. };
  211.  
  212. unsigned long wReg[80];
  213.  
  214. #define CLS(R, S)  (((R) >> (31 - S)) | ((R) << S))
  215. #define ROUND00_15(R) \
  216.   aReg2 = CLS(aReg1, 5) + ((bReg1 & cReg1) | (~bReg1 & dReg1)) + \
  217.     eReg1 + (wReg[R] = yReg[R]) + kReg[R]; \
  218.   bReg2 = aReg1; \
  219.   cReg2 = CLS(bReg1, 30); \
  220.   dReg2 = cReg1; \
  221.   eReg2 = dReg1; \
  222.   wReg[R + 1] = yReg[R + 1]; \
  223.   aReg1 = CLS(aReg2, 5) + ((bReg2 & cReg2) | (~bReg2 & dReg2)) + \
  224.     eReg2 + (wReg[R + 1] = yReg[R + 1]) + kReg[R + 1]; \
  225.   bReg1 = aReg2; \
  226.   cReg1 = CLS(bReg2, 30); \
  227.   dReg1 = cReg2; \
  228.   eReg1 = dReg2
  229. #define ROUND16_19(R) \
  230.   aReg2 = CLS(aReg1, 5) + ((bReg1 & cReg1) | (~bReg1 & dReg1)) + \
  231.     eReg1 + \
  232.     (wReg[R] = wReg[R - 16] ^ wReg[R - 14] ^ \
  233.       wReg[R - 8] ^ wReg[R - 3]) + \
  234.     kReg[R]; \
  235.   bReg2 = aReg1; \
  236.   cReg2 = CLS(bReg1, 30); \
  237.   dReg2 = cReg1; \
  238.   eReg2 = dReg1; \
  239.   aReg1 = CLS(aReg2, 5) + ((bReg2 & cReg2) | (~bReg2 & dReg2)) + \
  240.     eReg2 + \
  241.     (wReg[R + 1] = wReg[R + 1 - 16] ^ wReg[R + 1 - 14] ^ \
  242.       wReg[R + 1 - 8] ^ wReg[R + 1 - 3]) + \
  243.     kReg[R + 1]; \
  244.   bReg1 = aReg2; \
  245.   cReg1 = CLS(bReg2, 30); \
  246.   dReg1 = cReg2; \
  247.   eReg1 = dReg2
  248. #define ROUND20_39_60_79(R) \
  249.   aReg2 = CLS(aReg1, 5) + ((bReg1 ^ cReg1 ^ dReg1)) + \
  250.     eReg1 + \
  251.     (wReg[R] = wReg[R - 16] ^ wReg[R - 14] ^ \
  252.       wReg[R - 8] ^ wReg[R - 3]) + \
  253.     kReg[R]; \
  254.   bReg2 = aReg1; \
  255.   cReg2 = CLS(bReg1, 30); \
  256.   dReg2 = cReg1; \
  257.   eReg2 = dReg1; \
  258.   aReg1 = CLS(aReg2, 5) + ((bReg2 ^ cReg2 ^ dReg2)) + \
  259.     eReg2 + \
  260.     (wReg[R + 1] = wReg[R + 1 - 16] ^ wReg[R + 1 - 14] ^ \
  261.       wReg[R + 1 - 8] ^ wReg[R + 1 - 3]) + \
  262.     kReg[R + 1]; \
  263.   bReg1 = aReg2; \
  264.   cReg1 = CLS(bReg2, 30); \
  265.   dReg1 = cReg2; \
  266.   eReg1 = dReg2
  267. #define ROUND40_59(R) \
  268.   aReg2 = CLS(aReg1, 5) + ((bReg1 & cReg1) | (bReg1 & dReg1) | \
  269.     (cReg1 & dReg1)) + \
  270.     eReg1 + \
  271.     (wReg[R] = wReg[R - 16] ^ wReg[R - 14] ^ \
  272.       wReg[R - 8] ^ wReg[R - 3]) + \
  273.     kReg[R]; \
  274.   bReg2 = aReg1; \
  275.   cReg2 = CLS(bReg1, 30); \
  276.   dReg2 = cReg1; \
  277.   eReg2 = dReg1; \
  278.   aReg1 = CLS(aReg2, 5) + ((bReg2 & cReg2) | (bReg2 & dReg2) | \
  279.     (cReg2 & dReg2)) + \
  280.     eReg2 + \
  281.     (wReg[R + 1] = wReg[R + 1 - 16] ^ wReg[R + 1 - 14] ^ \
  282.       wReg[R + 1 - 8] ^ wReg[R + 1 - 3]) + \
  283.     kReg[R + 1]; \
  284.   bReg1 = aReg2; \
  285.   cReg1 = CLS(bReg2, 30); \
  286.   dReg1 = cReg2; \
  287.   eReg1 = dReg2
  288.  
  289. void
  290. hSHA(unsigned long *yReg)
  291. {
  292.   unsigned long aReg1 = mdQ[0], bReg1 = mdQ[1], cReg1 = mdQ[2],
  293.     dReg1 = mdQ[3], eReg1 = mdQ[4];
  294.   unsigned long aReg2, bReg2, cReg2, dReg2, eReg2;
  295.   ROUND00_15(0);
  296.   ROUND00_15(2);
  297.   ROUND00_15(4);
  298.   ROUND00_15(6);
  299.   ROUND00_15(8);
  300.   ROUND00_15(10);
  301.   ROUND00_15(12);
  302.   ROUND00_15(14);
  303.   ROUND16_19(16);
  304.   ROUND16_19(18);
  305.   ROUND20_39_60_79(20);
  306.   ROUND20_39_60_79(22);
  307.   ROUND20_39_60_79(24);
  308.   ROUND20_39_60_79(26);
  309.   ROUND20_39_60_79(28);
  310.   ROUND20_39_60_79(30);
  311.   ROUND20_39_60_79(32);
  312.   ROUND20_39_60_79(34);
  313.   ROUND20_39_60_79(36);
  314.   ROUND20_39_60_79(38);
  315.   ROUND40_59(40);
  316.   ROUND40_59(42);
  317.   ROUND40_59(44);
  318.   ROUND40_59(46);
  319.   ROUND40_59(48);
  320.   ROUND40_59(50);
  321.   ROUND40_59(52);
  322.   ROUND40_59(54);
  323.   ROUND40_59(56);
  324.   ROUND40_59(58);
  325.   ROUND20_39_60_79(60);
  326.   ROUND20_39_60_79(62);
  327.   ROUND20_39_60_79(64);
  328.   ROUND20_39_60_79(66);
  329.   ROUND20_39_60_79(68);
  330.   ROUND20_39_60_79(70);
  331.   ROUND20_39_60_79(72);
  332.   ROUND20_39_60_79(74);
  333.   ROUND20_39_60_79(76);
  334.   ROUND20_39_60_79(78);
  335.   mdQ[0] += aReg2;
  336.   mdQ[1] += bReg2;
  337.   mdQ[2] += cReg2;
  338.   mdQ[3] += dReg2;
  339.   mdQ[4] += eReg2;
  340. }
  341.  
  342. unsigned long dataBuffer[BLOCK_COUNT / 4];
  343.  
  344. int
  345. main(int argc, char **argv)
  346. {
  347.   int i;
  348.   for (i = 1; i < argc; i++) {
  349.     FILE *fp;
  350.     mdQ[0] = 0x67452301L;
  351.     mdQ[1] = 0xefcdab89L;
  352.     mdQ[2] = 0x98badcfeL;
  353.     mdQ[3] = 0x10325476L;
  354.     mdQ[4] = 0xc3d2e1f0L;
  355.     if ((fp = fopen(argv[i], "rb")) == NULL) {
  356.       fprintf(stderr, "sha: cannot open %s for reading\n", argv[i]);
  357.       continue;
  358.     }
  359.     initBuffer(fp);
  360.     while (readBuffer(fp, dataBuffer))
  361.       hSHA(dataBuffer);
  362.     printf("%08lx%08lx%08lx%08lx%08lx\t%s\n",
  363.       mdQ[0], mdQ[1], mdQ[2], mdQ[3], mdQ[4], argv[i]);
  364.     fclose(fp);
  365.   }
  366.   return EXIT_SUCCESS;
  367. }
  368.